package jeudame.Modele;

import jeudame.Vue.Monpanel;


/**
 * Class Damier: C'est la classe qui traitera la gestion du tableau de pièce
 * @author Bilal and David
 */
public class Damier
{
        /**
         * Boolean qui va nous permettre d'afficher les commentaires
         */
        boolean DEBUG = false;

        /**
         * Tableau de pièce
         */
	protected Piece[][] Damier;
        /**
         * Tableau de pièce qui nous servira pour les retours en arrière
         */
        protected Piece[][] DamierRetour;

        /**
         * Notre vue sur laquelle on est
         */
        protected Monpanel Vue;

        /**
         * Notre DamierModel qui correspond
         */
        protected DamierModel dModel;

        /**
         * Constructeur de la classe Damier avec paramètre
         * @param View La vue sur laquelle on est
         * @param dModel1 Le damierModel qui correspond
         */
        public Damier(Monpanel View, DamierModel dModel1)
        {



            Damier = new Piece[10][10];
            DamierRetour = new Piece[10][10];

            this.Vue= View;
            dModel=dModel1;
            initDamier();

        }

        /**
        * Initialise le damier pour un debut de partie
         *
        */
        private void initDamier(){//Prepare le damier en position de depart

            if(DEBUG){
                System.out.println("DEBUG : initDamier1");
            }


            int i,j;
            i=0;j=0;
            while(i<10){
                while(j<10){
                    Damier[i][j]=null;
                    DamierRetour[i][j]=null;
                    j++;
                }
                i++;
                j=0;
            }


            initLigne(0,0,"Blanc");
            initLigne(1,1,"Blanc");
            initLigne(0,2,"Blanc");
            initLigne(1,3,"Blanc");
            initLigne(1,9,"Noir");
            initLigne(0,8,"Noir");
            initLigne(1,7,"Noir");
            initLigne(0,6,"Noir");


            copie();
        }

        /**
        * Initialise une ligne pour un debut de partie
        * @param x
         *      l'ordonnee du debut de la ligne (0 si la premiere case est noir, 1 sinon)
         * @param y
         *      l'absisse du debut de la ligne
         * @param s
         *      La couleur de la piece ("Blanc" ou "Noir")
        */
        private void initLigne(int x, int y, String s){//Prepare une ligne en position de depart
            while(x<10){
                if (DEBUG) System.out.println("DEBUG : initLigne Damier["+x+"]["+y+"]=newPiece()");
                Damier[x][y] = new Piece(s);
                x=x+2;
            }
        }

        /**
        * Copie Damier dans DamierRetour
        */
        private void copie(){//permet de copier Damier sur DamierRetour
            int x = 0;
            int y = 0;

            while(x<10){
                while(y<10){
                    DamierRetour[x][y] = Damier[x][y];
                    y++;
                }
                x++;
                y=0;
            }
            if(DEBUG)  System.out.println("DEBUG : initDamier2");
 
        }

        /**
        * Permet de tester si le saut est possible et effectue le saut
        * @param x
         *      L'ordonnee du pion
         * @param y
         *      L'abcisse du pion
         * @param diffX
         *      La difference : ordonnee de depart - ordonnee arrivee
         * @param diffY
         *      La difference : abcisse de depart - abcisse arrivee
        * @return
         *      true si le saut est possible
         *      false si le saut est impossible
        */
        private boolean sautPion(int x, int y,int diffX,int diffY){

                        if(DEBUG) System.out.println("DEBUG : sautPion DEBUT");

                        if (Damier[x+(diffX/2)][y+(diffY/2)]==null){//il n'y a pas de pion a sauter

                            if(DEBUG) System.out.println("DEBUG : sautPion il n'y a pas de pion a sauter");

                            return false;
                        }
                        else{// il y a un pion a sauter
                            if(DEBUG) System.out.println("DEBUG : sautPion xDep =" +x+ " ydep= " +y+ "xFin =" +(x+(diffX/2))+ " yFin=" + (y+(diffY/2)));
                            if (Damier[x+(diffX/2)][y+(diffY/2)].getCamp().equalsIgnoreCase(Damier[x][y].getCamp())){//le pion a sauter est du mauvais camp
                                if(DEBUG) System.out.println("DEBUG : sautPion pion du meme camp"  );
                                return false;
                            }
                            else{//il y a bien un pion adversaire a sauter
                                if(DEBUG) { System.out.println("DEBUG : sautPion On peut manger Pion a manger : x="+(x+(diffX/2)) + "y= " + (y+(diffY/2)));
                                            System.out.println("DEBUG : sautPion On peut manger, Pion dest : x="+(x+(diffX)) + "y= " + (y+(diffY)));
                                            System.out.println("DEBUG : sautPion On peut manger, Pion src : x="+(x) + "y= " + (y));
                                }

                                Damier[x+diffX][y+diffY]=Damier[x][y];
                                Damier[x][y]=null;
                                manger(x+(diffX/2),y+(diffY/2));

                                if (DEBUG) System.out.println("DEBUG : sautPion() manger x = " + (x+(diffX/2))  + " y = " +(y+(diffY/2)));

                                this.Vue.PionMort(x+(diffX/2),y+(diffY/2));
                                this.Vue.repaint();
                                return true;
                            }
                        }

        }

        /**
        * Effectue le deplacement d'une dame si possible
        * @param yDep
         *      l'ordonne de depart du pion
         * @param xDep
         *      l'abcisse de depart du pion
         * @param yFin
         *      l'ordonne de fin du pion
         * @param xFin
         *      l'abcisse de fin du pion
        * @return
         *      true si le deplacement est possible
         *      false sinon
        */
        public boolean deplacerDame(int xDep, int yDep, int xFin, int yFin){

            if(DEBUG) System.out.println("DEBUG : deplacerDame DEBUT xDep = " + xDep + "yDep = "+yDep+"xFin="+xFin+"yFin="+yFin);

            Piece pTemp= Damier[xDep][yDep];
            Piece pInter=null;
            String camp = pTemp.getCamp();
            int diffX=xDep-xFin;
            int diffY=yDep-yFin;
            int i=0;
            int signeX = 0;
            int signeY = 0;
            int pInterX=0;
            int pInterY=0;

            if(Math.abs(diffX)!=Math.abs(diffY)){//Si le deplacement n'est pas en diagonal
                if(DEBUG) System.out.println("DEBUG : deplacerDame Mauvais deplacement");
                return false;
            }
            else if(Damier[xFin][yFin]!=null){
                return false;
            }
            else{//Le deplacement a un bonne direction et la destination est libre
                signeX=diffX/Math.abs(diffX);
                signeY=diffY/Math.abs(diffY);
                while(i<Math.abs(diffX)){
                    if(DEBUG) {System.out.println("DEBUG : deplacerDame camp = " + camp);
                        if(pInter!=null) System.out.println("DEBUG : deplacerDame pIntercamp = " + pInter.getCamp());

                    }

                    if (pInter!=null && Damier[xDep - (signeX*i)-signeX][yDep - (signeY*i)-signeY]!=null){
                        if(DEBUG) System.out.println("DEBUG : deplacerDame false : plusieurs pions dans la course");
                        return false;
                    }
                    if (pInter!=null && pInter.getCamp().equals(camp)){
                        if(DEBUG) System.out.println("DEBUG : deplacerDame false : Pion meme couleur dans la course");
                        return false;
                    }
                    i++;
                    if (pInter==null){
                        pInter=Damier[xDep - (signeX*i)][yDep - (signeY*i)];
                        pInterX = (xDep - (signeX*i));
                        pInterY = (yDep - (signeY*i));
                        if(DEBUG) System.out.println("DEBUG : deplacerDame pInterX = " +pInterX + " pInterY = " + pInterY );
                    }



                }
                Damier[xFin][yFin]=pTemp;
                Damier[xDep][yDep]=null;

                if(pInter!=null){
                    if(DEBUG) System.out.println("DEBUG : deplacerDame On mange! pTemp = " + pInter.getCamp() + " xInter="+pInterX+" yInter ="+pInterY);
                    this.manger(pInterX, pInterY);
                    this.Vue.PionMort(pInterX,pInterY);
                    this.Vue.repaint();
                }
                if(DEBUG) System.out.println("DEBUG : deplacerDame true");

                return true;
            }



        }

        /**
         *
         * @param xDep L'ordonnee de depart du pion
         * @param yDep L'absisse de depart du pion
         * @param xFin L'ordonnee de fin du pion
         * @param yFin l'absisse de fin du pion
         * @return
         *          true si le deplacement est possible
         *          false sinon
         */
        public boolean deplacer(int xDep, int yDep, int xFin, int yFin){

		Piece pTemp;
                int diffX;
                int diffY;

                if(DEBUG) System.out.println("DEBUG : deplacer DEBUT");

                try{

                    if(DEBUG) System.out.println("DEBUG : deplacer try");

                    if (Damier[xDep][yDep] != null){
                        pTemp=Damier[xDep][yDep];

                            diffX = xFin - xDep;
                            diffY = yFin - yDep;

                            if(pTemp.getCamp().equalsIgnoreCase("Noir")){

                            if(DEBUG) System.out.println("DEBUG : deplacerNoir Il y a une piece");

                            //On calcul la difference pour voir si l'action est conforme
                            //Une action est conforme si on avance d'un en diagonal ou deux en sautant un pion adverse

                                if ((diffX==1 || diffX==-1)&& (diffY==-1 )){

                                    Damier[xFin][yFin]=pTemp;
                                    Damier[xDep][yDep]=null;

                                    if(DEBUG) System.out.println("DEBUG : deplacerNoir diffx=1||-1 diffy=-1");

                                    return true;
                                }
                            }
                            else{
                                if ((diffX==1 || diffX==-1)&& (diffY==1 )){

                                    Damier[xFin][yFin]=pTemp;
                                    Damier[xDep][yDep]=null;

                                    if(DEBUG) System.out.println("DEBUG : deplacerNoir diffx=1||-1 diffy=-1");

                                    return true;
                                }
                            }

                            if((diffX==2|| diffX==-2) && (diffY==2 || diffY==-2)){
                                if(DEBUG) System.out.println("DEBUG : deplacerNoir xDep =" + xDep + " ydep =" + yDep + " xFin =" +xFin + " yFin =" +yFin);
                                if (sautPion(xDep, yDep, diffX, diffY)){
                                    return true;
                                }
                            }
                            if(DEBUG) System.out.println("DEBUG : deplacerNoir Deplacement interdit");

                            return false;

                            //////
                        }
                        else{
                                return false;//Pas de pion a cette selection
                        }


                }
                catch(Exception e){
                    if(DEBUG)
                                    System.out.println("DEBUG : deplacerNoir catch");
                    System.out.println(e.getMessage());
                    System.out.println(e.getStackTrace());
                    return false;
                }

	}

        /**
        * Verifie si le pion doit etre promu Dame ou non
        * @param y
         *      l'abcisse du pion
         * @param camp
         * @return
         *      true si le pion doit etre promu
         *      false sinon
        */
        public boolean checkPromotion(int y, String camp){

            if(camp.equalsIgnoreCase("Blanc")){
                if(y==9){
                    return true;
                }
                return false;
            }
            else{
                if(y==0){
                    return true;
                }
                return false;
            }
        }



        /**
        * Supprime un pion, informe la vue de la supression
        * @param x
         *      l'ordonne du pion
         * @param y
         *      l'abcisse du pion
        */
        public void manger( int x, int y)
        {
            int test=0;// Entier permettant de récupérer la valeur des confirmDialog
            if (Damier[x][y].getCamp().equalsIgnoreCase("Blanc"))
            {
                dModel.setNbPionBlanc((dModel.getNbPionBlanc()-1));
                this.Vue.MiseAJourNb_pion("Blanc", dModel.getNbPionBlanc());

                //Le jeu est terminé
                if(dModel.getNbPionBlanc()==0)
                {
                    javax.swing.JOptionPane.showMessageDialog(null, "Bien joué joueur 2! Tu as gagné!");
                    test=javax.swing.JOptionPane.showConfirmDialog(null, "Voulez-vous recommencer?", "Input", javax.swing.JOptionPane.YES_NO_OPTION); // On demande aux s'ils veulent recommencer
                    if(test==javax.swing.JOptionPane.YES_OPTION) // On réinitialise la fenêtre totalement
                    {
                        initfenetre();
                    }else // Sinon on quitte la fenêtre
                    {
                        System.exit(0);
                    }
                }
            }
            if (Damier[x][y].getCamp().equalsIgnoreCase("Noir"))
            {
                dModel.setNbPionNoir(dModel.getNbPionNoir()-1);
                this.Vue.MiseAJourNb_pion("Noir", dModel.getNbPionNoir());

                //Le jeu est terminé
                if(dModel.getNbPionNoir()==0)
                {
                    javax.swing.JOptionPane.showMessageDialog(null, "Bien joué joueur 1! Tu as gagné!");
                    test=javax.swing.JOptionPane.showConfirmDialog(null, "Voulez-vous recommencer?", "Input", javax.swing.JOptionPane.YES_NO_OPTION); // On demande aux s'ils veulent recommencer
                    if(test==javax.swing.JOptionPane.YES_OPTION) // On réinitialise la fenêtre totalement
                    {
                        initfenetre();
                    }else// Sinon on quitte la fenêtre
                    {
                        System.exit(0);
                    }
                }
            }
            if(DEBUG) System.out.println("DEBUG : manger() DEBUT");
            Damier[x][y]=null;
            this.Vue.repaint();

	}

        /**
         * Initialise toute la fenetre (quasiment tout les objets)
         */
        public void initfenetre()
        {
            this.Vue.initVue();
            dModel.InitDamierModel();
            initDamier();
            this.Vue.repaint();
        }

         /**
         *
         * @param xDep
         *      l'ordonne de depart du pion
         * @param yDep
         *      l'abcisse de depart du pion
         * @param xFin
         *      l'ordonne de fin du pion
         * @param yFin
         *      l'abcisse de fin du pion
         * @return
         */
        public boolean deplacerPion(int xDep, int yDep, int xFin, int yFin){

            if(Damier[xFin][yFin]!=null)
                return false;
            if (Damier[xDep][yDep].isDame()){
                if(DEBUG) System.out.println("DEBUG : deplacerPion On deplace une dame");
                if(this.deplacerDame(xDep, yDep, xFin, yFin))
                    return true;
                return false;
            }

            /*else if(Damier[xDep][yDep].getCamp().equalsIgnoreCase("Blanc"))
            {
                if(DEBUG) System.out.println("DEBUG : deplacerPion On deplace un pion Blanc");
                if(deplacerBlanc(xDep, yDep, xFin, yFin)){
                    if(checkPromotion(yFin, Damier[xFin][yFin].getCamp()))
                    {
                        Damier[xFin][yFin].setDame(true);
                        if(DEBUG) System.out.println("DEBUG PROMOTION DAME  xfin="+xFin+" yfin="+yFin);
                        javax.swing.JOptionPane.showMessageDialog(null, "Bien joué! Tu as crée une dame!");
                    }
                    return true;
                }
            }
            else{
                if(deplacerNoir(xDep, yDep, xFin, yFin)){
                    if(DEBUG) System.out.println("DEBUG : deplacerPion On deplace un pion Noir");
                    if(checkPromotion(yFin, Damier[xFin][yFin].getCamp()))
                    {
                        if(DEBUG) System.out.println("DEBUG PROMOTION DAME  xfin="+xFin+" yfin="+yFin);
                        Damier[xFin][yFin].setDame(true);
                        javax.swing.JOptionPane.showMessageDialog(null, "Bien joué! Tu as crée une dame!");
                    }
                    return true;
                }
            }*/
            else if (deplacer(xDep, yDep, xFin, yFin)){
                if(checkPromotion(yFin, Damier[xFin][yFin].getCamp()))
                    {
                        Damier[xFin][yFin].setDame(true);
                        if(DEBUG) System.out.println("DEBUG PROMOTION DAME  xfin="+xFin+" yfin="+yFin);
                        javax.swing.JOptionPane.showMessageDialog(null, "Bien joué! Tu as crée une dame!");
                    }
                    return true;
            }
            return false;
        }

        /**
         *
         * @param x
         *      l'ordonne du pion
         * @param y
         *      l'abcisse du pion
         */
        public void checkDame(int x, int y){
            if(DEBUG) System.out.println("DEBUG CHECK DAME  xfin="+x+" yfin="+y);
            if(Damier[x][y].isDame()){
                Vue.TransformerDame(Damier[x][y].getCamp(), x, y);
            }

        }

         /**
         *
         * @param x
         *      l'ordonne du pion
         * @param y
         *      l'abcisse du pion
         * @return
         *      la couleur de la piece
         */
        public String getPieceColor(int x, int y){
            if (DEBUG) System.out.println("DEBUG getPieceColor x=" +x +" y=" +y);
            if(Damier[x][y]!=null)
                return Damier[x][y].getCamp();
            return "";
        }
}
